/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */


package com.android1.amarena2d.nodes;

import com.android1.amarena2d.engine.EngineObject;
import com.android1.amarena2d.nodes.behavior.HasLifecycleObserver;
import com.android1.amarena2d.nodes.behavior.HasVisibility;
import com.android1.amarena2d.nodes.behavior.LifecyleTick;
import com.android1.amarena2d.nodes.behavior.Tagged;
import com.android1.amarena2d.nodes.behavior.delegates.LifecycleObserver;
import com.android1.amarena2d.nodes.behavior.delegates.LifecycleObserverDelegate;
import com.android1.amarena2d.nodes.behavior.delegates.TimerDelegate;
import com.android1.amarena2d.nodes.behavior.delegates.TimerDelegateImpl;

//

public abstract class BaseLifecycleObject extends EngineObject implements LifecycleObject, LifecyleTick, Tagged, HasVisibility, HasLifecycleObserver {

    protected boolean init;
    protected boolean active = true;
    protected boolean running = false;
    protected boolean visible = true;

    public String tag;

    protected TimerDelegate timerDelegate;
    protected LifecycleObserverDelegate lifecycleObserverDelegate;

    protected BaseLifecycleObject() {

    }

    public TimerDelegate timer() {
        if (timerDelegate == null)
            timerDelegate = new TimerDelegateImpl(this);
        return timerDelegate;
    }

    @Override
    public LifecycleObserver lifecylce() {
        if (lifecycleObserverDelegate == null)
            lifecycleObserverDelegate = new LifecycleObserverDelegate();
        return lifecycleObserverDelegate;
    }

    @Override
    public void tick(final float d) {
        if (!running || !active || !init)
            return;
        onTick(d);
    }

    protected void onTick(final float d) {

    }

    @Override
    public void init() {
        init = true;
        onInit();
        if (lifecycleObserverDelegate != null)
            lifecycleObserverDelegate.onInit();
    }

    protected void onInit() {

    }

    @Override
    public void dispose() {
        init = false;
        onDispose();
        if (lifecycleObserverDelegate != null)
            lifecycleObserverDelegate.onDispose();

    }

    protected void onDispose() {

    }

    @Override
    public void enter() {
        running = true;
        if (!init)
            init();
        if (timerDelegate != null)
            timerDelegate.resumeTimer();
        onEnter();
        if (lifecycleObserverDelegate != null)
            lifecycleObserverDelegate.onEnter();
    }

    protected void onEnter() {

    }

    @Override
    public void exit() {
        if (timerDelegate != null)
            timerDelegate.pauseTimer();
        running = false;
        onExit();
        if (lifecycleObserverDelegate != null)
            lifecycleObserverDelegate.onExit();
    }

    protected void onExit() {

    }

    @Override
    public void render() {
        if (!init || !active || !visible)
            return;
    }

    @Override
    public boolean isPlaying() {
        return running;
    }

    @Override
    public boolean isActive() {
        return active;
    }

    @Override
    public boolean isVisible() {
        return visible;
    }

    @Override
    public void setVisible(boolean visible) {
        this.visible = visible;
    }

    @Override
    public boolean isInit() {
        return init;
    }

    @Override
    public String getTag() {
        return tag;
    }

    public void setTag(String tag) {
        this.tag = tag;
    }
}